home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / DCLAP 4j / DClap / DView.cpp < prev    next >
Encoding:
Text File  |  1995-12-17  |  10.3 KB  |  382 lines  |  [TEXT/R*ch]

  1. // DView.cp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include "DView.h"
  6. #include "DViewCentral.h"
  7.  
  8. #include "DApplication.h"
  9.  
  10. //class DView : public DTaskMaster
  11.  
  12.  
  13. DView::DView(long id, Nlm_Handle nlmObject, long kind, DTaskMaster* superior, 
  14.     DList* subordinates) :
  15.         DTaskMaster(id, superior, subordinates),
  16.         fHresize(fixed),
  17.         fVresize(fixed),
  18.         fNlmObject(nlmObject),
  19.         fKind(kind)
  20. {
  21.     this->Initialize();
  22. }
  23.  
  24. DView::DView( long id, Nlm_Handle nlmObject, ResizeMethod Hresize, ResizeMethod Vresize,
  25.                  long kind, DTaskMaster* superior, DList* subordinates) :
  26.         DTaskMaster(id, superior, subordinates),
  27.         fHresize(Hresize),
  28.         fVresize(Vresize),
  29.         fNlmObject(nlmObject),
  30.         fKind(kind)
  31. {
  32.     this->Initialize();
  33. }
  34.  
  35. void DView::Initialize()
  36. {
  37.     Nlm_LoadRect(&fViewrect, 0, 0, 0, 0);
  38.     Nlm_LoadRect(&fSizerange, 0, 0, 32500, 32500);
  39.     if (fId) gViewCentral->RegisterView(this);  // do this for all new views ?!
  40.     this->SetNlmObject(fNlmObject);  
  41. }
  42.  
  43.     
  44. DView::~DView() 
  45. {
  46.         // !!!!!!!!!!!!!     FIXED 20 mar 94 w/ DeleteSubviews  !!!!!!!!!!!!!
  47.             
  48.         // we HAD a BIG memory leak here, as most of view methods
  49.         // are written assuming that deleting a superview will auto-delete all subviews
  50.         // BUT we never got around to fixing this, as we need to negotiate it w/ Vibrant
  51.         // who also removes subviews at each call to Nlm_Remove(), but it doesn't remove
  52.         // our Objects... just its own.  So whatever recursive call to RemoveAllSubviews
  53.         // we need to fiddle w/ fNlmObject so Nlm_Remove() doesn't try to removed gone objects
  54.         
  55.         // *****************
  56.  
  57.  
  58.     DeleteSubviews();
  59.  
  60.      
  61.     if (fNlmObject) {
  62.         Nlm_SetObject((Nlm_GraphiC)fNlmObject, NULL); //????
  63.  
  64.          // THIS IS A BIG HACK, but it may solve several of the messy crashes
  65.          // on Quit due to this messy vibrant-dclap interface
  66.          // (vibrant is insisting on drawing to non-existant views thru
  67.          //  its remove callbacks...)
  68.         if (!gApplication->fDone) Nlm_Remove(fNlmObject); 
  69.         }
  70.     fNlmObject= NULL;
  71.     gViewCentral->RemoveView(fId); // ?? this calls back here??
  72. }
  73.  
  74.  
  75.  
  76. void DView::DeleteSubviews()
  77. {
  78.     /// tricky part: tell superior Nlm object to forget about its subordinates, so it
  79.     /// doesn't try to delete them also !
  80.  
  81.     if (fSubordinates) {
  82.         Nlm_Handle aNlmHand = NULL;
  83.         Nlm_GraphiC aNlmChild= NULL;
  84.         //if (fNlmObject) aNlmChild= Nlm_GetChild(fNlmObject);
  85.         
  86.         long i, n= fSubordinates->GetSize();
  87.         for (i= 0; i<n; i++) {
  88.             DView* subord= (DView*)fSubordinates->At(i);
  89.             if (subord) {
  90.                 subord->DeleteSubviews(); 
  91.                 aNlmHand= Nlm_Parent(subord->fNlmObject);
  92.                 if (aNlmHand && aNlmHand == fNlmObject) 
  93.                     Nlm_SetChild((Nlm_GraphiC)fNlmObject, NULL);                
  94.                 delete subord;
  95.                 }
  96.             }        
  97.         fSubordinates->suicide(); //delete  ~DTaskMaster does this, but we need to do it now... ?
  98.         fSubordinates= NULL;
  99.         }
  100. }
  101.  
  102.  
  103. // from Vibrant vibincld.h // This should be public info !?
  104. typedef  struct  Nlm_graphicrec {
  105.   Nlm_GraphiC   next;
  106.   Nlm_GraphiC   parent;
  107.   Nlm_GraphiC   children;
  108.   Nlm_GraphiC   lastChild;
  109.   Nlm_GphPrcs   PNTR classptr;
  110.   Nlm_ActnProc  action;
  111.   Nlm_RecT      rect;
  112.   Nlm_Boolean   enabled;
  113.   Nlm_Boolean   visible;
  114.   Nlm_VoidPtr   thisobject; /* <<<add to hold DObjectPtr dgg++ */
  115. } Nlm_GraphicRec, Nlm_GraphicData, PNTR Nlm_GphPtr;
  116.  
  117. extern "C" void  Nlm_GetGraphicData PROTO((Nlm_GraphiC a, Nlm_GraphicData PNTR gdata));
  118. extern "C" void  Nlm_SetGraphicData PROTO((Nlm_GraphiC a, Nlm_GraphicData PNTR gdata));
  119. extern "C" void Nlm_SetNext PROTO((Nlm_GraphiC a, Nlm_GraphiC nxt));
  120. extern "C" Nlm_GraphiC Nlm_GetNext PROTO((Nlm_GraphiC a));
  121.  
  122. void DView::RemoveSubview( DView* aSubview, Nlm_Boolean doDeleteIt)
  123. {
  124.     if (aSubview) {
  125.         if (fSubordinates) {
  126.           Nlm_GraphicData  gdata;
  127.           Nlm_GraphiC theNlmview= (Nlm_GraphiC)aSubview->fNlmObject;
  128.             Nlm_Handle aNlmHand= Nlm_Parent( aSubview->fNlmObject);
  129.             if (aNlmHand && aNlmHand == fNlmObject) {
  130. #if 1
  131.                 Nlm_GetGraphicData((Nlm_GraphiC)fNlmObject, &gdata);
  132.                 if (gdata.children) {
  133.                     if (gdata.lastChild && gdata.lastChild != gdata.children) {
  134.                   Nlm_GraphiC last= NULL, next= NULL, p;
  135.                   p = gdata.children;
  136.                   while (p) {
  137.                     next = Nlm_GetNext(p);
  138.                       if (p == theNlmview) { // remove p from chain
  139.                                 if (last) Nlm_SetNext( last, next);
  140.                                 else gdata.children= next;
  141.                                 if (p == gdata.lastChild) gdata.lastChild= last;
  142.                       }
  143.                     else
  144.                         last = p;
  145.                     p= next;
  146.                       }
  147.                         }
  148.                     else if (gdata.children == theNlmview)
  149.                         gdata.children= NULL; // only child == theNlmview !?
  150.                     Nlm_SetGraphicData ((Nlm_GraphiC)fNlmObject, &gdata);
  151.                     }
  152. #else
  153.                 //Nlm_GraphiC chld= Nlm_GetChild( (Nlm_GraphiC)fNlmObject);
  154.                     // ! this alone is bad if there is more than one subview for this !
  155.                 Nlm_SetChild( (Nlm_GraphiC)fNlmObject, NULL);    
  156. #endif
  157.                 }            
  158.         fSubordinates->Delete( aSubview);
  159.             }
  160.         if (doDeleteIt) {
  161.             aSubview->DeleteSubviews(); 
  162.             delete aSubview;
  163.             }
  164.         }
  165. }
  166.  
  167. Nlm_CharPtr DView::GetTitle(char* title, ulong maxsize) 
  168.     if (title==NULL) title= (char*) MemNew(maxsize); //new char[maxsize];
  169.     Nlm_GetTitle( fNlmObject, title, maxsize);
  170.     return title;
  171. }
  172.     
  173. void DView::SetNlmObject(Nlm_Handle nlmObject) 
  174.     fNlmObject= nlmObject; 
  175.     if (fNlmObject) {
  176.         Nlm_SetObject((Nlm_GraphiC)fNlmObject, this);  
  177.         Nlm_ObjectRect( fNlmObject, &fViewrect);  
  178.         }
  179. }        
  180.  
  181. void DView::SetSuperior(Nlm_Handle newSuper) 
  182.     Nlm_SetParent( (Nlm_GraphiC)fNlmObject, (Nlm_GraphiC)newSuper); 
  183. }
  184.  
  185. void DView::SetWindow( DWindow* newWindow)
  186. {
  187.     if (!newWindow) Dgg_SetParentWindow( (Nlm_GraphiC)GetNlmObject(), NULL);
  188.   else Dgg_SetParentWindow( (Nlm_GraphiC)GetNlmObject(), 
  189.                                             (Nlm_WindoW) ((DView*)newWindow)->GetNlmObject() );
  190. }
  191.  
  192.  
  193. void DView::InvalRect(Nlm_RecT& r) 
  194. {
  195.     Nlm_WindoW w= Nlm_SavePort( fNlmObject);
  196. #ifdef WIN_MOTIF
  197.     this->Select();
  198. #endif
  199.     Nlm_InvalRect( &r);
  200.     // Nlm_RestorePort( w); //<<!! THIS CALLS UPDATER !!!!!!
  201.     if (w) Nlm_UseWindow (w); 
  202. }
  203.  
  204. void DView::Invalidate(void) 
  205.     Nlm_WindoW w= Nlm_SavePort( fNlmObject);
  206. #ifdef WIN_MOTIF
  207.     this->Select();
  208. #endif
  209.     Nlm_InvalObject(fNlmObject);  // naughty vib -- Nlm_Inval doesn't check current port...
  210.     // Nlm_RestorePort( w); //<<!! THIS CALLS UPDATER !!!!!!
  211.     if (w) Nlm_UseWindow (w); 
  212. }
  213.  
  214. void DView::Show(void) 
  215. {  
  216.     Invalidate(); //?? need now that we pulled out vibwndws/Nlm_RestorePort/Update call
  217.     Nlm_Update();
  218.     Nlm_Show(fNlmObject); 
  219. }
  220.  
  221. void DView::Hide(void) 
  222. {  
  223.     //Nlm_RecT  r;
  224.     //ViewRect( r);
  225.     //Nlm_EraseRect( &r);
  226.     Nlm_Hide(fNlmObject); 
  227.     //Nlm_Update();
  228. }
  229.  
  230. void DView::SetSizerange(Nlm_RecT r) 
  231. {
  232.     fSizerange= r;
  233.   ViewRect(fViewrect); // GetPosition(fViewrect);
  234.     fViewrect.left  = Max( fSizerange.left, fViewrect.left);
  235.     fViewrect.top   = Max( fSizerange.top, fViewrect.top);
  236.     fViewrect.right = Min( fViewrect.right, fSizerange.right);
  237.     fViewrect.bottom= Min( fViewrect.bottom, fSizerange.bottom);
  238.   this->SetPosition(fViewrect);
  239. }
  240.  
  241.  
  242.  
  243.     // !!?? Vibrant windows (& others) have no GetPosition callback & return 0 for position !!!????
  244.     // FIX THIS thru DView -- have one sane function (getposition/viewrect), not two at
  245.     // odds and incomplete -- use GetPosition when want to include scrollbar size
  246.     // or revise this somehow
  247.     
  248. void DView::ViewRect(Nlm_RecT& r) 
  249.     Nlm_ObjectRect(fNlmObject, &r);  
  250. }
  251.  
  252. void DView::GetPosition(Nlm_RecT& r) 
  253.     Nlm_GetPosition(fNlmObject, &r); 
  254.     if (Nlm_EmptyRect( &r)) Nlm_ObjectRect(fNlmObject, &r);
  255.     fViewrect= r; 
  256. }
  257.  
  258. void DView::SetPosition(Nlm_RecT& r) 
  259.     Nlm_RecT testr;
  260.     Nlm_GetPosition(fNlmObject, &testr); 
  261.     Boolean hasSetposition= (!Nlm_EmptyRect( &testr));
  262.     
  263.     if (hasSetposition) Nlm_SetPosition(fNlmObject, &r);
  264.     else Nlm_SetRect((Nlm_GraphiC)fNlmObject, &r);
  265.     fViewrect= r;
  266. }
  267.  
  268.  
  269. void DView::SizeToSuperview( DView* super, Boolean horiz, Boolean vert)
  270. {
  271. //#ifndef WIN_MSWIN
  272. #ifdef WIN_MAC
  273.     // the other win systems seem bothered by this...
  274.     // if this is enabled in motif, motif fails to move scrollbars !
  275.     
  276.     Nlm_RecT r, myr; 
  277.     // GetPosition includes size of scrollbars for slates, etc
  278.     super->ViewRect(r); //super->GetPosition(r);  
  279.     this->GetPosition(myr); //ViewRect(myr);   
  280.     if (horiz) {
  281.         myr.left = 0; 
  282.         myr.right= myr.left + (r.right - r.left) +1; 
  283.         }
  284.     if (vert) {
  285.         myr.top = 0;
  286.         myr.bottom = myr.top + (r.bottom - r.top) +1;
  287.         }
  288.     SetPosition( myr);
  289. #endif
  290. }
  291.  
  292.  
  293. void DView::ResizeSubviews(DView* superview, Nlm_PoinT sizechange)
  294. {
  295.     this->Resize(superview, sizechange);
  296.     if (fSubordinates) {
  297.         long i, n= fSubordinates->GetSize();
  298.         for (i= 0; i<n; i++) {
  299.             DView* subord= (DView*)fSubordinates->At(i);
  300.             if (subord) subord->ResizeSubviews(this, sizechange); 
  301.             }        
  302.         }
  303. }
  304.  
  305. void DView::Resize(DView* superview, Nlm_PoinT sizechange)
  306. {
  307.     Nlm_RecT    super;
  308.     short    wid, hgt, oldw, oldh, top, oldt, left, oldl;
  309.     
  310.     GetPosition(fViewrect); // mac: this one is *required*, in DTableView w/ scrollbars
  311.     //ViewRect(fViewrect); // mac: this one makes too small a resize for DTableView
  312.     left= oldl= fViewrect.left;
  313.     top= oldt= fViewrect.top;
  314.     wid= oldw= fViewrect.right  - left;
  315.     hgt= oldh= fViewrect.bottom - top;
  316.     
  317.     // want point & rect classes like MacApp that can iterate over to save us this dup?
  318.     switch (fHresize) {
  319.         case matchsuper: 
  320. #ifdef WIN_MAC
  321.     // problems w/ this w/ mswin, xwin -- need to fiddle to get it right
  322.             if (superview) { 
  323.                 superview->ViewRect(super);    
  324.                 left = 0; 
  325.                 wid  = super.right - super.left + 1; 
  326.                 }
  327.             else
  328.                 wid += sizechange.x;
  329.             break;
  330. #endif
  331.         case relsuper    : wid += sizechange.x; break;
  332.         case moveinsuper: left += sizechange.x; break;
  333.         case calculate: wid = this->CalculateNewSize(false, wid, sizechange.x); break;
  334.         case fixed    :
  335.         default            : break;
  336.         }
  337.         
  338.     switch (fVresize) {
  339.         case matchsuper: 
  340. #ifdef WIN_MAC
  341.             if (superview) { 
  342.                 superview->ViewRect(super);    
  343.                 top = 0;
  344.                 hgt = super.bottom - super.top + 1;
  345.                 }
  346.             else
  347.                 hgt += sizechange.y;
  348.             break;
  349. #endif
  350.         case relsuper    : hgt += sizechange.y; break;
  351.         case moveinsuper: top += sizechange.y; break;
  352.         case calculate: hgt = this->CalculateNewSize(true, hgt, sizechange.y); break;
  353.         case fixed        :
  354.         default                : break;
  355.         }
  356.     
  357.     if (oldw != wid || oldh != hgt || oldl != left || oldt != top) {
  358.         fViewrect.left  = Max( fSizerange.left, left);
  359.         fViewrect.top   = Max( fSizerange.top, top);
  360.         fViewrect.right = Min( Max( fViewrect.left+1, fViewrect.left + wid), fSizerange.right);
  361.         fViewrect.bottom= Min( Max( fViewrect.top+1, fViewrect.top + hgt), fSizerange.bottom);
  362.         this->Select(); // motif requires !!
  363.       this->SetPosition(fViewrect);
  364.       
  365. #if 0
  366. //#ifdef WIN_MOTIF
  367.       // !! in Motif, nothing is drawn in resized area, and scrollbars, etc, disappear 
  368.       this->Select(); 
  369.       this->Hide();  
  370.       this->Show();  
  371. #endif
  372.       }
  373. }
  374.  
  375.